package com.hly.girl.shiro;

import org.apache.commons.collections.map.HashedMap;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class MyRealm  extends AuthorizingRealm {

    Map<String,String> userMap = new HashedMap(16);
    {
       // userMap.put("hly","202cb962ac59075b964b07152d234b70"); //加密
        userMap.put("hly","6a855b873a49703125eab20222efde86");//加盐：现在加的盐为用户名        该值为用户名+密码
        //        userMap.put("hly","123");
        super.setName("myRealm");
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String userName = (String) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo simpleAuthorizationInfo =  new SimpleAuthorizationInfo();

        //从数据库或者缓存中获取角色数据
        Set<String> roles = getRolesByUserName(userName);
        simpleAuthorizationInfo.setRoles(roles);

        //权限数据类似的就不写了
//        Set<String> permissions = getPermissionByUserName(userName);
//        simpleAuthorizationInfo.setObjectPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    /**
     * 模拟数据库中获取角色数据
     * @param userName
     * @return
     */
    private Set<String> getRolesByUserName(String userName) {
       Set<String> set = new HashSet<>();
       set.add("admin");
       set.add("user");
        return set;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //1.从主体传过来的认证信息中，获得用户名
        String userName = (String) authenticationToken.getPrincipal();
        //2.通过用户名到数据库中获取凭证
        String password  = getPasswordByUserName(userName);

        if(password==null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                "hly",password,"myRealm"
                );
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("hly"));
        return authenticationInfo;
    }

    /**
     * 模拟数据库查询凭证
     * @param userName
     * @return
     */
    private String getPasswordByUserName(String userName) {
        return userMap.get(userName);
    }

    public static  void main (String[] arg){
        Md5Hash md5Hash = new Md5Hash("hly123");
        System.out.println(md5Hash.toString());
    }
}
